--------------------------------------------------------------------------------
--                          OutputIEEE_FP32_to_BF16
--                          (OutputIEEE_8_23_to_8_7)
-- This operator is part of the Infinite Virtual Library FloPoCoLib
-- All rights reserved 
-- Authors: F. Ferrandi  (2009-2012)
--------------------------------------------------------------------------------
-- Pipeline depth: 1 cycles

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library std;
use std.textio.all;
library work;

entity OutputIEEE_FP32_to_BF16 is
   port ( clk, rst, ce : in std_logic;
          X : in  std_logic_vector(8+23+2 downto 0);
          R : out  std_logic_vector(15 downto 0)   );
end entity;

architecture arch of OutputIEEE_FP32_to_BF16 is
signal expX, expX_d1 :  std_logic_vector(7 downto 0);
signal fracX :  std_logic_vector(22 downto 0);
signal exnX, exnX_d1 :  std_logic_vector(1 downto 0);
signal sX, sX_d1 :  std_logic;
signal expZero :  std_logic;
signal sfracX, sfracX_d1 :  std_logic_vector(22 downto 0);
signal resultLSB, resultLSB_d1 :  std_logic;
signal roundBit, roundBit_d1 :  std_logic;
signal sticky, sticky_d1 :  std_logic;
signal round :  std_logic;
signal expfracR0 :  std_logic_vector(14 downto 0);
signal fracR :  std_logic_vector(6 downto 0);
signal expR :  std_logic_vector(7 downto 0);
begin
   process(clk)
      begin
         if clk'event and clk = '1' then
            if ce = '1' then
               expX_d1 <=  expX;
               exnX_d1 <=  exnX;
               sX_d1 <=  sX;
               sfracX_d1 <=  sfracX;
               resultLSB_d1 <=  resultLSB;
               roundBit_d1 <=  roundBit;
               sticky_d1 <=  sticky;
            end if;
         end if;
      end process;
   expX  <= X(30 downto 23);
   fracX  <= X(22 downto 0);
   exnX  <= X(33 downto 32);
   sX  <= X(31) when (exnX = "01" or exnX = "10" or exnX = "00") else '0';
   expZero  <= '1' when expX = (7 downto 0 => '0') else '0';
   -- since we have one more exponent value than IEEE (field 0...0, value emin-1),
   -- we can represent subnormal numbers whose mantissa field begins with a 1
   sfracX <= '1' & fracX(22 downto 1) when (expZero = '1' and exnX = "01") else fracX;
   -- wFO < wFI, need to round fraction
   resultLSB <= sfracX(16);
   roundBit <= sfracX(15);
   sticky <=  '0' when sfracX(14 downto 0) = CONV_STD_LOGIC_VECTOR(0,14) else '1';
   ----------------Synchro barrier, entering cycle 1----------------
   round <= roundBit_d1 and (sticky_d1 or resultLSB_d1);
   -- The following addition will not overflow since FloPoCo format has one more exponent value
   expfracR0 <= (expX_d1 & sfracX_d1(22 downto 16))  +  (CONV_STD_LOGIC_VECTOR(0,14) & round);
   fracR <= 
      (6 downto 0 => '0') when (exnX_d1 = "00") else
      expfracR0(6 downto 0) when (exnX_d1 = "01") else 
      (6 downto 1 => '0') & exnX_d1(0);
   expR <=  
      (7 downto 0 => '0') when (exnX_d1 = "00") else
      expfracR0(14 downto 7) when (exnX_d1 = "01") else 
      (7 downto 0 => '1');
   R <= sX_d1 & expR & fracR; 
end architecture;

